/*
 * Copyright (C) 2021 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.example.distschedule.slice;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.example.distschedule.ResourceTable;
import com.example.distschedule.bean.DeviceResult;
import com.example.distschedule.bean.ProductResult;
import com.example.distschedule.bean.RespondBase;
import com.example.distschedule.rx2.OKHttpUtilsRx2;
import com.example.distschedule.toast.XToastUtils;
import com.example.distschedule.utils.CommonUtil;
import com.example.distschedule.utils.NFCData;
import com.example.distschedule.utils.PreferencesUtil;
import com.example.distschedule.utils.TLVUtil;
import com.socks.library.KLog;
import io.reactivex.disposables.Disposable;
import ohos.aafwk.ability.AbilitySlice;
import ohos.aafwk.content.Intent;
import ohos.aafwk.content.Operation;
import ohos.agp.components.Component;
import ohos.agp.components.Text;
import ohos.utils.zson.ZSONObject;
import ohos.wifi.WifiDevice;
import ohos.wifi.WifiLinkedInfo;
import okhttp3.MediaType;
import okhttp3.RequestBody;
import org.apache.commons.lang3.StringUtils;

import java.util.Objects;
import java.util.Optional;

/**
 * 添加设备页面
 *
 *
 */
public class AddDeviceAbilitySlice extends AbilitySlice {
    private int typeId;
    private NFCData nfcData;
    private String originalSsid; // 原本连接的ap热点
    private Text tips;
    private Text toWifiSettingText;
    private Component retryComp;

    @Override
    public void onStart(Intent intent) {
        super.onStart(intent);
        super.setUIContent(ResourceTable.Layout_ability_add_device);
        String paramsFormJS = (String) intent.getParams().getParam("__startParams");
        // 无感配网模块netconfig跳转回来
        if (!StringUtils.isEmpty(paramsFormJS)) {
            JSONObject jsonObject = JSONObject.parseObject(paramsFormJS);
            String deviceId = (String) jsonObject.get("deviceId");
            if (!StringUtils.isEmpty(deviceId)) {
                CommonUtil.judgeDevice(getContext(), deviceId, new Intent());
                terminateAbility();
            }
        } else {
            // 碰一碰进入页面
            getNfcInfo();
            initComponents();
            originalSsid = getCurrentSsid();
        }
    }

    private void initComponents() {
        findComponentById(ResourceTable.Id_add_device_img_back).setClickedListener(component -> goBackHome());
        tips = (Text) findComponentById(ResourceTable.Id_add_text_tips);
        toWifiSettingText = (Text) findComponentById(ResourceTable.Id_add_text_set_wifi);

        retryComp = findComponentById(ResourceTable.Id_add_text_retry);
        retryComp.setClickedListener(this::retry);
        // 初始化组件显示
        switch (nfcData.getNetTag()) {
            case NFCData.NET_TAG_NOT_NET_DEVICE: {
                XToastUtils.error("该设备不支持配网");
                tips.setText("该设备不支持配网，若支持请检查NFC tag=4 字段的数据");
                break;
            }
            default: {
                tips.setText("准备配网中~");
                break;
            }
        }
    }

    @Override
    public void onActive() {
        super.onActive();
        // socket配网 检查是否已经连上该网络
        if (NFCData.NET_TAG_SOCKET.equals(nfcData.getNetTag())) {
            if (getCurrentSsid().equals(nfcData.getApSSID())) {
                toNetBySocket();
            }
        }
    }

    @Override
    public void onForeground(Intent intent) {
        super.onForeground(intent);
    }

    /**
     * 获取当前连接的wifi名称
     *
     * @return name
     */
    private String getCurrentSsid() {
        WifiDevice wifiDevice = WifiDevice.getInstance(getContext());
        // 调用WLAN连接状态接口，判断当前设备是否已连接到WLAN
        boolean isConnected = wifiDevice.isConnected();
        if (isConnected) {
            // 获取wifi连接信息
            Optional<WifiLinkedInfo> linkedInfo = wifiDevice.getLinkedInfo();
            // 获取连接wifi 的 ssid
            if (linkedInfo.isPresent()){
                return linkedInfo.get().getSsid();
            }
        }
        return "";
    }

    /**
     * 获取nfc数据
     */
    private void getNfcInfo() {
        Object businessInfo = Objects.requireNonNull(getAbility().getIntent().getParams()).getParam("businessInfo");
        if (businessInfo != null) {
            ZSONObject businessInfoZSON = ZSONObject.classToZSON(businessInfo);
            // data91 is your device sn in nfc tag.
            try {
                String data91 = businessInfoZSON.getZSONObject("params").getString("91");
                nfcData = TLVUtil.getNFCData(data91);
                // 从NFC贴纸读取
                KLog.i("deviceAPSsid：" + nfcData.getApSSID());
                getDeviceInfo();
            } catch (Exception e) {
                XToastUtils.error("NFC自定义数据解析错误，请对照profile自行检查");
                KLog.e("NFC自定义数据解析错误，请对照profile自行检查");
            }
        }
    }

    /**
     * 点击重试
     * @param component
     */
    private void retry(Component component){
        if (NFCData.NET_TAG_NAN.equals(nfcData.getApSSID())){
            // NAN配网需要多hap安装，若无跳转则是netconfig模块为安装
            XToastUtils.info("若重试后无跳转，请检查项目是否勾选Deploy Multi Hap Packages的安装方式");
        }
        getNfcInfo();
    }

    private void getDeviceInfo() {
        String deviceId = nfcData.getDeviceId();
        String userId = PreferencesUtil.getUserId(getContext());
        OKHttpUtilsRx2.INSTANCE.getApi().getDeviceInfo(deviceId, userId)
                .compose(OKHttpUtilsRx2.INSTANCE.ioMain())
                .subscribe(new OKHttpUtilsRx2.SubjectImpl<RespondBase<DeviceResult>>() {
                    @Override
                    public void onNext(RespondBase<DeviceResult> deviceInfo) {
                        // 设备在线
                        if (deviceInfo.isSuccess() && deviceInfo.getResult().isOnline()) {
                            typeId = deviceInfo.getResult().getTypeId();
                            CommonUtil.judgeDevice(getContext(), nfcData.getDeviceId(), new Intent());
                        } else if (deviceInfo.isSuccess()) {
                            // 设备离线
                            toNetConfigPage();
                        } else {
                            // 设备未注册
                            getDefaultName(nfcData.getProductId());
                        }
                    }

                    @Override
                    public void onError(Throwable throwable) {
                        super.onError(throwable);
                    }

                    @Override
                    public void onComplete() {
                        super.onComplete();
                    }

                    @Override
                    protected Object clone() throws CloneNotSupportedException {
                        return super.clone();
                    }

                    @Override
                    public void onSubscribe(Disposable disposable) {
                        super.onSubscribe(disposable);
                        KLog.i("查询设备状态中...");
                    }
                });
    }

    /**
     * 获取品类名字作为默认名字
     *
     * @param productId 品类ID
     */
    private void getDefaultName(String productId) {
        OKHttpUtilsRx2.INSTANCE.getApi().getNameByProId(productId)
                .compose(OKHttpUtilsRx2.INSTANCE.ioMain())
                .subscribe(new OKHttpUtilsRx2.SubjectImpl<RespondBase<ProductResult>>() {
                    @Override
                    public void onNext(RespondBase<ProductResult> respond) {
                        super.onNext(respond);
                        KLog.i(respond);
                        if (respond.isSuccess()) {
                            typeId = respond.getResult().getId();
                            addDevice(typeId, respond.getResult().getName());
                        }
                    }
                });
    }

    private void addDevice(int typeId, String name) {
        JSONObject body = new JSONObject();
        body.put("id", nfcData.getDeviceId());
        body.put("name", name);
        body.put("ownerId", PreferencesUtil.getUserId(getContext()));
        body.put("secret", nfcData.getDevicePwd());
        body.put("typeId", typeId);
        KLog.i("OKHttpUtilsRx2", body);
        OKHttpUtilsRx2.INSTANCE.getApi().addDevice(RequestBody.create(MediaType.parse("application/json;charset=UTF-8"), JSON.toJSONString(body)))
                .compose(OKHttpUtilsRx2.INSTANCE.ioMain())
                .subscribe(new OKHttpUtilsRx2.SubjectImpl<RespondBase>() {
                    @Override
                    public void onNext(RespondBase respond) {
                        super.onNext(respond);
                        KLog.i(respond);
                        if (respond.isSuccess()) {
                            getContext().getUITaskDispatcher().asyncDispatch(() -> {
                                XToastUtils.info("添加设备成功");
                            });
                            toNetConfigPage();
                        }
                    }
                });
    }

    private void toNetConfigPage() {
        switch (nfcData.getNetTag()) {
            case NFCData.NET_TAG_NOT_NET_DEVICE: {
                XToastUtils.error("该设备不需要配网");
                break;
            }
            case NFCData.NET_TAG_NAN: {
                toNetConfig();
                break;
            }
            case NFCData.NET_TAG_SOCKET: {
                setSocketNetMode();
                break;
            }
            case NFCData.NET_TAG_BLE: {
                XToastUtils.info("蓝牙配网，敬请期待");
                break;
            }
            default: {
                XToastUtils.error("nfc net tag字段错误");
                KLog.e("nfc net tag字段错误");
                break;
            }
        }
    }

    private void setSocketNetMode() {
        tips.setText("请将手机wifi连接到" + nfcData.getApSSID());
        retryComp.setVisibility(Component.HIDE);
        toWifiSettingText.setVisibility(Component.VISIBLE);
        toWifiSettingText.setClickedListener(this::toSetWifi);
    }

    private void toSetWifi(Component component) {
        Intent intent = new Intent();
        Operation operation =
                new Intent.OperationBuilder()
                        .withBundleName("com.android.settings")
                        .withAbilityName("com.android.settings.Settings$WifiSettingsActivity")
                        .withFlags(Intent.FLAG_NOT_OHOS_COMPONENT)
                        .build();
        intent.setOperation(operation);
        startAbility(intent);
    }

    /**
     * 无感配网
     */
    private void toNetConfig() {
        String sessionId = getAbility().getIntent().getStringParam("nanSessionId");
        Intent intent = new Intent();
        Operation operation =
                new Intent.OperationBuilder()
                        .withDeviceId("")
                        .withBundleName(getBundleName())
                        .withAbilityName("com.example.netconfig.MainAbility")
                        .build();
        intent.setOperation(operation);
        // 设备热点名
        intent.setParam("targetDeviceId", nfcData.getApSSID());
        intent.setParam("sessionId", sessionId);
        intent.setParam("deviceId", nfcData.getDeviceId());
        startAbility(intent);
        terminateAbility();
    }

    /**
     * softap socket配网
     */
    private void toNetBySocket() {
        Intent intent = new Intent();
        intent.setParam("deviceId", nfcData.getDeviceId());
        intent.setParam("originalSsid", originalSsid);
        startAbility(intent);
        present(new SocketNetConfigSlice(), intent);
        terminate();
    }

    private void goBackHome() {
        onBackPressed();
    }
}
